Added Vector support for primitive methods.#68
Added Vector support for primitive methods.#68rhys-h-walker wants to merge 6 commits intoSOM-st:masterfrom
Conversation
| vm_oop_t VMVector::RemoveObj(vm_oop_t other) { | ||
| const int64_t first = INT_VAL(load_ptr(this->first)); | ||
| const int64_t last = INT_VAL(load_ptr(this->last)); | ||
| VMArray* storage = load_ptr(this->storage); | ||
|
|
||
| for (int64_t i = first - 1; i < last - 1; ++i) { | ||
| vm_oop_t current = storage->GetIndexableField(i); | ||
|
|
||
| // Check where integers are tagged or references can be checked | ||
| if (current == other) { | ||
| Remove(NEW_INT(i - first + 2)); // Convert to 1-indexing | ||
| return load_ptr(trueObject); | ||
| } | ||
| } | ||
| return load_ptr(falseObject); | ||
| } | ||
|
|
||
| vm_oop_t VMVector::Remove(vm_oop_t inx) { | ||
| const int64_t first = INT_VAL(load_ptr(this->first)); | ||
| int64_t last = INT_VAL(load_ptr(this->last)); | ||
| VMArray* storage = load_ptr(this->storage); | ||
| int64_t index = INT_VAL(inx); | ||
|
|
||
| if ((last - first) != 0 && index == 0) { | ||
| index = index; | ||
| } | ||
|
|
||
| if (index < 1 || index > last - first) { | ||
| IndexOutOfBounds(); | ||
| } |
There was a problem hiding this comment.
This code here is a bit odd. I think Remove(inx) is not used anywhere else, and allocating an int here seems unnecessary for a helper.
But the code is also too general, I think.
If this is truly only a helper for RemoveObj() (if I didn't miss anything), then it doesn't need to handle the failure case, i.e., IndexOutOfBounds
760116b to
e979852
Compare
6943b96 to
87dc7f3
Compare
|
@rhys-h-walker I just rebased this PR, and did a bit of work on the flag you added. Thanks! |
a265562 to
c704ef4
Compare
841644d to
6cdab1e
Compare
This implements Vector in the interpreter, and most of its methods as primitives. The implementation uses the new VMVector class as representation. The #contains: and #indexOf: can’t work it in the current SOM++ design. Because when sending a message, we yield back to the bytecode loop, which is not recursive, and thus, can’t come back to the primitive code. The `USE_VECTOR_PRIMITIVES` compilation flag is `true` per default and allows disabling the use of the vector primitives/strategy. The implementation supports AWFY/Vector and core-lib/Vector and loads the correct primitive methods for each implementation. Methods are hashed with murmur3_32 to determine whether primitives are applicable. These hashes can now be shown by running SOM++ with the -prim-hashes flag. Adapt PrimitiveContainer to store a pair of primitives, with their bytecode hash. Also reduce the code duplication in InstallPrimitives by using template parameters and function pointers. Co-authored-by: Stefan Marr <git@stefan-marr.de>
This avoid exploding the number of configurations that need to be run in CI. Feels a bit too much to double it. It also makes sure the USE_VECTOR_PRIMITIVE flag is configured for unit tests. Signed-off-by: Stefan Marr <git@stefan-marr.de>
Signed-off-by: Stefan Marr <git@stefan-marr.de>
Signed-off-by: Stefan Marr <git@stefan-marr.de>
- fix Main.cpp Signed-off-by: Stefan Marr <git@stefan-marr.de>
This allows us to use the flag in CI and check that the hashes are correct. Signed-off-by: Stefan Marr <git@stefan-marr.de>
This PR implements the standard
Vectorclass as well as theVectorfrom the Are We Fast Yet benchmarks as primitives. The Vector object is represented byVMVectorand most ofVector's methods are lowered to primitives.The use of
VMVectorand the primitives is controlled by theUSE_VECTOR_PRIMITIVEScompilation flag, which istrueper default and allows disabling the use of the vector primitives/strategy.Methods are hashed with murmur3_32 to determine whether primitives are applicable.
These hashes can now be shown by running SOM++ with the -prim-hash-check flag, which causes an error when the hashes do not match. This is used in CI for testing that the core-lib and primitives match.
Limitations
Because SOM++ is implemented as a non-recursive interpreter, primitives cannot make message sends that need to return execution to the primitive.
This means, we cannot lower any method that needs to activate a block passed as a parameter, and we can't implement
#contains:and#indexOf:, because they rely on the#=message to determine equality.